#include <bits/stdc++.h>

#define rep(i, j, k) for (int i = (j); i <= (k); ++i)
#define per(i, j, k) for (int i = (j); i >= (k); --i)
#define SZ(v) int((v).size())
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second
using ll = long long;
using pii = std::pair<int, int>;
using pll = std::pair<ll, ll>;

template<class T>inline void chkmn(T &x, T y) { if (y < x) x = y; }
template<class T>inline void chkmx(T &x, T y) { if (y > x) x = y; }

using namespace std;

const int maxn = 2000010;

int n, sa[maxn], ksa[maxn], rnk[maxn], lenp[maxn], lens[maxn], fa[maxn][21];
int id[maxn], pid[maxn], tot, op[maxn], cf[maxn], lim[maxn], res[maxn];
vector<pii> neq;
vector<int> vec[maxn];

int find(int x, int k) {
  return fa[x][k] == x ? x : fa[x][k] = find(fa[x][k], k);
}

void merge(int x, int y, int k) {
  fa[find(x, k)][k] = find(y, k);
}

void work() {
  cin >> n;
  rep (i, 1, n) cin >> sa[i], sa[i]++, ksa[i] = sa[i];
  sort(ksa + 1, ksa + n + 1);
  rep (i, 1, n) if (ksa[i] != i) return cout << "-1\n", void();
  rep (i, 1, n) rnk[sa[i]] = i;
  rnk[n + 1] = 0;
  rep (i, 1, n - 1) cin >> lenp[i] >> lens[i];
  cin >> lenp[n];
  neq.clear();
  rep (j, 0, 20) rep (i, 1, 2 * n) fa[i][j] = i;
  rep (i, 1, n) {
    if (!(lenp[i] & 1)) return cout << "-1\n", void();
    lenp[i] >>= 1;
    int l = i - lenp[i], r = i + lenp[i], len = r - l + 1, p1 = l, p2 = n - r + 1 + n;
    if (l < 1 || r > n) return cout << "-1\n", void();
    per (j, 20, 0) if (len >> j & 1) merge(p1, p2, j), p1 += (1 << j), p2 += (1 << j);
    if (l - 1 >= 1 && r + 1 <= n) neq.emplace_back(l - 1, r + 1);
  }
  rep (i, 1, n - 1) {
    if (lens[i] & 1) return cout << "-1\n", void();
    lens[i] >>= 1;
    if (!lens[i]) {
      neq.emplace_back(i, i + 1);
      continue;
    }
    int l = i - lens[i] + 1, r = i + lens[i], len = r - l + 1, p1 = l, p2 = n - r + 1 + n;
    if (l < 1 || r > n) return cout << "-1\n", void();
    per (j, 20, 0) if (len >> j & 1) merge(p1, p2, j), p1 += (1 << j), p2 += (1 << j);
    if (l - 1 >= 1 && r + 1 <= n) neq.emplace_back(l - 1, r + 1);
  }
  per (j, 20, 1) rep (i, 1, 2 * n - (1 << j) + 1) {
    int k = find(i, j);
    if (k == i) continue;
    merge(i, k, j - 1), merge(i + (1 << (j - 1)), k + (1 << (j - 1)), j - 1);
  }
  rep (i, 1, n) merge(i, n - i + 1 + n, 0);
  rep (i, 1, n) id[i] = find(i, 0), pid[i] = id[i];
  sort(pid + 1, pid + n + 1), tot = unique(pid + 1, pid + n + 1) - pid - 1;
  rep (i, 1, n) id[i] = lower_bound(pid + 1, pid + tot + 1, id[i]) - pid;
  rep (i, 1, tot) vec[i].clear();
  rep (i, 1, n) vec[id[i]].emplace_back(i);
  // 0: =, 1: <, 2: <=
  rep (i, 1, n - 1) {
    if (rnk[sa[i] + 1] <= rnk[sa[i + 1] + 1]) op[i] = 2;
    else op[i] = 1;
  }
  rep (i, 1, n) cf[i] = 0;
  rep (i, 1, tot) {
    int l = n + 1, r = 0;
    for (int x : vec[i]) chkmn(l, rnk[x]), chkmx(r, rnk[x]);
    cf[l]++, cf[r]--;
  }
  rep (i, 1, n) cf[i] += cf[i - 1];
  rep (i, 1, n - 1) if (cf[i] && op[i] == 1) return cout << "-1\n", void();
  rep (i, 1, n - 1) if (cf[i]) op[i] = 0;
  rep (i, 1, n) lim[i] = n;
  for (pii info : neq) {
    int x = rnk[info.fi], y = rnk[info.se];
    if (x > y) swap(x, y);
    chkmn(lim[x], y - 1);
  }
  int tmp = n;
  rep (i, 1, n - 1) {
    chkmn(tmp, lim[i]);
    if (op[i] == 1) {
      tmp = n;
    } else if (op[i] == 0) {
      if (tmp == i) return cout << "-1\n", void();
    } else {
      if (tmp == i) op[i] = 1, tmp = n;
    }
  }
  int sig = 1;
  res[sa[1]] = sig;
  rep (i, 1, n - 1) {
    if (op[i] == 1) sig++;
    res[sa[i + 1]] = sig;
  }
  rep (i, 1, n) if (res[i] > 26) return cout << "-1\n", void();
  rep (i, 1, n) cout << char('a' - 1 + res[i]);
  cout << '\n';
}

int main() {
  freopen("string.in", "r", stdin);
  freopen("string.out", "w", stdout);
  cin.tie(nullptr) -> ios::sync_with_stdio(false);
  int t; cin >> t;
  while (t--) work();
}